#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<ctype.h>

// 标准输出重定向文件，/tmp路径实在Linux系统在内存里做的一个文件系统，放在这里不用写硬盘程序运行会快一些
#define TMP_FILE		"/tmp/.ifconfig.log"

int main(int argc, char **argv)
{
	pid_t		pid;
	int			fd;
	char		buf[1024];
	int			rv;
	char		*ptr;
	FILE		*fp;
	char		*ip_start;
	char		*ip_end;
	char		ipaddr[16];

	//父进程打开这个文件，子进程继承文件描述符，父子进程都可以通过各自的文件描述符访问同一个文件
	if( (fd=open(TMP_FILE, O_RDWR|O_CREAT|O_TRUNC, 0644)) < 0 )
	{
		printf("Redirect standard output to file failure: %s\n", strerror(errno));
		return -1;
	}

	//父进程创建进程
	pid = fork();
	if( pid < 0 )
	{
		printf("fork() cteate child process failure: %s\n", strerror(errno));
		return -1;
	}
	else if( pid == 0 )
	{
		printf("Child process start excute ifconfig program\n");

		//子进程继承文件描述符，子进程重定向标准输出到父进程打开的文件里
		dup2(fd, STDOUT_FILENO);
		execl("/sbin/ifconfig", "ifconfig", "eth0", NULL);
		//execl函数不会返回，因为他去执行另一个程序，如果返回，说明系统调用出错了
		printf("Child process excute another program, will not return here. Return here means execl() error\n");
		return -1;
	}
	else
	{
		sleep(3);		//父进程等待3s，让子进程先执行
	}

	//子进程调用execl()，会丢掉父进程文本段，所以子进程不会执行到这里，只有父进程会继续执行后面的代码
	
	memset(buf, 0, sizeof(buf));

	//父进程此时读不到内容，因为子进往文件写内容时已经将文件偏移量修改到文件尾了
	rv=read(fd, buf, sizeof(buf));
	printf("Read %d bytes data dierectly read after child process write\n", rv);

	//设置文件偏移量到文件头才能读文件
	memset(buf, 0, sizeof(buf));
	lseek(fd, 0, SEEK_SET);
	rv=read(fd, buf, sizeof(buf));
	printf("Read %d bytes data after lseek:\n %s\n", rv, buf);

	//想一行一行地读取文件内容，使用fdopen()函数文件描述符fd转成文件流fd
	fp = fdopen(fd, "r");

/* 	if( fp == NULL )
	{
		printf("fp error!\n");
	}
*/
	fseek(fp, 0, SEEK_SET);
	while( fgets(buf, sizeof(buf), fp) )
	{
		if( strstr(buf, "netmask") )
		{
			//字符串比对，找到IP地址
			ptr=strstr(buf, "inet");
			if( !ptr )
			{
				break;
			}
			ptr += strlen("inet");
			//inet后不知道时空格还是Tab，使用isblank()函数判断，如果字符还是空白格往后跳过
			while( isblank(*ptr) )
					ptr++;
			ip_start = ptr;
			//取到ptr第一个空白格为止
			while( !isblank(*ptr) )
			{
				ptr++;
			}
			ip_end = ptr;

			//memcpy()函数将IP地址拷贝到buffer中
			memset(ipaddr, 0, sizeof(ipaddr));
			memcpy(ipaddr, ip_start, ip_end-ip_start);		//ip_start起始地址，ip_end-ip_start为IP地址长度
			
			break;
		}
	}
	printf("Parser and get IP address: %s\n", ipaddr);

	fclose(fp);
	unlink(TMP_FILE);		//删除临时文件`

	return 0;
}


